package puntaelena.facilitylocation.hillclimbing.solver.agents;

import puntaelena.facilitylocation.hillclimbing.solver.services.ICoalitionsListener;
import puntaelena.facilitylocation.hillclimbing.solver.services.IFcltLocDataService;
import puntaelena.graphsupport.FacilitiesGraph;
import jfuzzyprincepless.agents.BaseNegotiationAgent;
import jfuzzyprincepless.negotiation.INegotiationContext;
import static puntaelena.facilitylocation.hillclimbing.solver.agents.FcltCityNegotiateComputator.*;

public class CityChoosesFacilityAgent
	extends BaseNegotiationAgent
{
	private int city;
	private double eps = 1e-5;

	public CityChoosesFacilityAgent(int city) {
		this.city = city;
	}

	@Override
	public boolean negotiate(INegotiationContext context) {
		IFcltLocDataService flServ =
			context.getService(IFcltLocDataService.class);
		FacilitiesGraph fgraph = flServ.getFgraph();
		int[] witnesses = flServ.getWitnesses();
		boolean[] isFcltOpen = flServ.getFcltOpen();
		
		context.getService(ICoalitionsListener.class).onCityBeg();
		double profit = computeBestWitnessProfit(
			fgraph,
			witnesses,
			isFcltOpen,
			city,
			true
		);
		if (profit > -eps) {
			flServ.increaseSolutionVersion();
		}
		context.getService(ICoalitionsListener.class).onCityEnd();

		return false;
	}

	public double getReadyToPay(
		INegotiationContext context,
		FacilitySearchsFriendCitiesAgent fagent
	) {
		IFcltLocDataService flServ =
			context.getService(IFcltLocDataService.class);
		int witness = flServ.getWitnesses()[city];
		if (witness == -1) {
			return flServ.getFgraph().getInfEdgeValue();
		}
		double curPay = flServ.getFgraph()
			.getFSEdge(city, flServ.getWitnesses()[city]);
		double altPay = flServ.getFgraph()
			.getFSEdge(city, fagent.getFacility());
		return Math.max(0, curPay - altPay);
	}

	public int getCity() {
		return city;
	}

	public double getBestLinkProfit(
		FacilitiesGraph fgraph,
		int[] witnesses,
		boolean[] isFcltOpen
	) {
		return FcltCityNegotiateComputator
			.computeBestWitnessProfit(
				fgraph,
				witnesses,
				isFcltOpen,
				city
			);
	}
}